######################################################
#该脚本实现的目标为：写一次，可以重复使用，轻松对应新增、修改的补丁文件。
#该脚本可以识别那些是新增补丁，那些是更新补丁，针对新增补丁生成备份，回退脚本。同时生成新增，更新的补丁列表。
#最终我们会有4个文件被生成，custodybak.sh 更新文件备份脚本 custodyReDo.sh 更新文件回退脚本 
#custodyCP.sh 文件替换脚本 pachesList.txt 补丁文件列表。
######################################################

###公用变量部分
##获取工程的根目录的绝对路径，后面的操作都以此为基点。
root_path=`find /opt/IBM/WebSphere/AppServer/profiles  -name  custody.war | grep installedApps`
#获取当前日期yyyyMMdd格式
curDate=`date "+%Y%m%d%H"`
##新增（减去脚本文件本身），更新文件计数
insertNum=-1
updateNum=0

##打印当前补丁中文件的列表到数组files中
files=($(find ./ -type f))
##遍历files数组，通过字符串方式获取到文件名，文件类型，及文件从 custody.war 开始的路径标识（用于find 命令过滤条件）
##用了识别新增或是更新的补丁文件，可以找到路径则为更新，否则为新增
##针对更新文件生成备份脚本
for i in "${files[@]}"; do 
 
  ##去掉补丁文件列表中的./符号
  myfile=${i#*/}
  ##获取补丁文件名称
  fileName=${myfile##*/}
  ##获取补丁文件类型
  fileType=${myfile##*.}
  ##获取去掉类型的补丁文件路径，方便对find结果集进行过滤
  fileTypeLess=${myfile%.*}
  
  ##根据补丁信息获取补丁在应用中的真实路径
  ptemp=`find  $root_path  -name $fileName | grep $fileTypeLess`
  ##获取真实路径的长度
  plen=${#ptemp}
 
 ##20的意思是说项目中所有文件的绝对路径的长度都大于20个字符。这样就说明在补丁包中的这个文件不是新增的而是更新的。
 ##所以需要针对该路径所指示的文件进行备份。
 ##if 语句的语法比较死板，if [ $plen  -gt 20 ] 每个部分的空格都不能少，需求知晓。
  if [ $plen  -gt 20 ];then
    ##该分支中为更新的文件
    #更新计数
     let updateNum=updateNum+1 
     #获取去掉类型的文件真实路径，方便备份及回退
     typeLessPath=${ptemp%.*}
     #生成备份脚本
     echo "cp "$ptemp" "$typeLessPath$curDate"."$fileType".bak" >> custodybak.sh
     #生成回退脚本
     echo "cp "$typeLessPath$curDate"."$fileType".bak  "$ptemp >> custodyReDo.sh
     #将补丁信息插入到文件表文件中，前缀 更新
     echo 更新 custody/$myfile >> pachesList.txt
  else
    ##该分支中为新增的文件
    #新增计数
    let insertNum=insertNum+1 
    #将补丁信息插入到文件表文件中，前缀 新增
    echo 新增 custody/$myfile >> pachesList.txt
  fi
  
  ##for test info
  #echo $ptemp
  #echo ${#ptemp}
  #echo  $root_path
  #echo  $fileName
  #echo  $fileTypeLess
  #echo  $ptemp
done

##校验逻辑部分
echo we have  $updateNum "files/file need to be updated"
echo we have  $insertNum "files/file need to be inserted"
#求补丁包中补丁文件总数
let  total=$updateNum+$insertNum
#向备份脚本插入验证过程
echo 'curDate=`date "+%Y%m%d%H"`' >> custodybak.sh
echo 'bakstat=`find /opt/IBM/WebSphere/AppServer/profiles  -name  *"$curDate"* | wc -l`' >> custodybak.sh
echo "echo 备份好的文件个数是："'$bakstat' 个 >> custodybak.sh
echo "echo 当前补丁包共有："$total 个文件 >> custodybak.sh
echo "echo 其中有 $insertNum 个是新增文件" >> custodybak.sh

###文件拷贝区,用来生成文件复制脚本。这个部分代码需要严格依赖补丁包的目录结构。所以补丁包的目录结构要和应用中文件的目录结构保持一致。
##获取当前补丁包中包含哪些补丁目录
arrDir=($(ls -l | grep "^d"))
#获取数组长度
dirSize=${#arrDir[@]}
##从8开始，step为9的原因是 ls -l | grep "^d" 的执行结果类似于 drwxrwxr-x 5 tgyyusr tgyyusr  4096 Oct 18 10:49 your_directory_name
## 而字符串 drwxrwxr-x 5 tgyyusr tgyyusr  4096 Oct 18 10:49 放到数组中后会被用空格分开，这样真正需要的目录名是在第9个,故循环step为9，
## 从0开始数第一个有用的数据下标就是8
for((i=8;i<$dirSize;i=i+9));do
 #获取当前变量
 dirName=${arrDir[$i]}
 #生成替换文件脚本
 echo "cp -r "$dirName" "$root_path >> custodyCP.sh
 
 ##for test info
 #echo $i
 #echo $dirName
done
echo "echo 文件替换完成！" >> custodyCP.sh

#对生成的脚本赋可执行权限
chmod +x custodybak.sh
chmod +x custodyReDo.sh
chmod +x custodyCP.sh